package helper.base

import kotlin.math.floor

object BaseTypeHelper {
    fun Boolean.toInt(
    ): Int {
        return if (this) {
            1
        } else {
            0
        }
    }

    fun Int.toBoolean(
    ): Boolean {
        return this != 0
    }

    fun Int.toSting(
    ): String {
        return "$this"
    }

    fun Int.toIntRange(): IntRange {
        return this..this
    }

    fun Double.isInt(): Boolean {
        return this == floor(this) && !this.isInfinite()
    }

    object ListExpand {
        fun ArrayList<Int>.toStringArrayList(
        ): ArrayList<String> {
            val arr = ArrayList<String>()
            map {
                arr.add("$it")
            }
            return arr
        }

        fun <E> List<E>.toArrayList(
        ): ArrayList<E> {
            return ArrayList(this)
        }

        fun <E> Array<out E>.toArrayList(
        ): ArrayList<E> {
            return this.toList().toArrayList()
        }

        fun List<Double>.getMinValueKey(
        ): Int? {
            var minValue = Double.MAX_VALUE
            var minIndex: Int? = null
            for ((index, value) in this.withIndex()) {
                if (value <= minValue) {
                    minValue = value
                    minIndex = index
                }
            }
            return minIndex
        }

        fun <T> ArrayList<T>.retainPercentage(percentage: Double) {
            if (percentage < 0.0 || percentage > 1.0) {
                throw IllegalArgumentException("Percentage must be between 0.0 and 1.0")
            }

            val retainSize = (this.size * percentage).toInt()

            if (this.isNotEmpty() && retainSize > 0) {
                this.subList(retainSize, this.size).clear()
            } else {
                this.clear()
            }
        }
    }

    object LHMGetExpand {
        fun <E, N : Number> A2LHM<E, N>.getEntry(
            compare: (Double, Double) -> Boolean
        ): Map.Entry<E, N>? {
            var selectedEntry: Map.Entry<E, N>? = null
            for (entry in this) {
                if (selectedEntry == null || compare(
                        entry.value.toDouble(),
                        selectedEntry.value.toDouble()
                    )
                ) {
                    selectedEntry = entry
                }
            }
            return selectedEntry
        }

        fun <E, N : Number> A2LHM<E, N>.getMinEntry(
        ): Map.Entry<E, N>? {
            return getEntry { value, selected ->
                value <= selected
            }
        }

        fun <E, N : Number> A2LHM<E, N>.getMaxEntry(
        ): Map.Entry<E, N>? {
            return getEntry { value, selected ->
                value >= selected
            }
        }

        fun <E, N : Number> A2LHM<E, N>.getMinKey(
        ): E? {
            return getMinEntry()?.key
        }

        fun <E, N : Number> A2LHM<E, N>.getMaxKey(
        ): E? {
            return getMaxEntry()?.key
        }
    }
}